package com.qingyun.system.service.impl;

import com.qingyun.system.config.properties.BaiduProperties;
import com.qingyun.system.service.BaiduAIService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
@RequiredArgsConstructor
@Slf4j
public class BaiduAIServiceImpl implements BaiduAIService {

    private final BaiduProperties baiduProperties;
    private final OkHttpClient httpClient = new OkHttpClient();

    @Override
    public String getAccessToken() throws IOException {
        String tokenUrl = "https://aip.baidubce.com/oauth/2.0/token";
        String params = "grant_type=client_credentials"
                + "&client_id=" + baiduProperties.getApiKey()
                + "&client_secret=" + baiduProperties.getSecretKey();

        Request request = new Request.Builder()
                .url(tokenUrl + "?" + params)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return extractToken(response.body().string());
        }
    }
    @Override
    public String idCardRecognition(String imageUrl, boolean isFront) throws IOException {
        String accessToken = getAccessToken();

        // 包含新增的功能参数
        String params = "url=" + imageUrl +
                "&id_card_side=" + (isFront ? "front" : "back") +
                "&detect_ps=true" +
                "&detect_risk=true" +
                "&detect_quality=true" +
                "&detect_direction=true";

        RequestBody body = RequestBody.create(params, MediaType.parse("application/x-www-form-urlencoded"));

        Request request = new Request.Builder()
                .url(baiduProperties.getIdCardUrl() + "?access_token=" + accessToken)
                .post(body)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("意外的 HTTP 响应代码: " + response.code());
            }

            String responseBody = response.body().string();

            // 使用 error_code 判断响应是否有效
            if (responseBody.contains("\"error_code\"")) {
                String errorCode = extractField(responseBody, "error_code");
                String errorMsg = extractField(responseBody, "error_msg");
                throw new IOException("身份证识别失败。错误代码：" + errorCode + ", Message: " + errorMsg);
            }

            // 确认是否包含有效的字段
            if (!responseBody.contains("words_result")) {
                throw new IOException("身份证识别的响应格式无效： " + responseBody);
            }

            return responseBody;
        }
    }


    @Override
    public String validateIdCard(String frontImageUrl, String backImageUrl) throws Exception {
        try {
            // 验证身份证正面
            String frontResult = idCardRecognition(frontImageUrl, true);
            validateImageStatus(frontResult, true);

            // 验证身份证反面
            String backResult = idCardRecognition(backImageUrl, false);
            validateImageStatus(backResult, false);

            // 如果都通过，则返回身份证正面信息
            return String.format(frontResult);
        } catch (Exception e) {
            // 如果任意一面失败，抛出异常并返回失败信息
            throw new Exception("身份证验证失败。正面和背面都必须有效。细节： " + e.getMessage());
        }
    }

    private void validateImageStatus(String responseResult, boolean isFront) throws Exception {
        String imageStatus = extractField(responseResult, "image_status");
        String riskType = extractField(responseResult, "risk_type");

        // 判断 image_status 是否为 "normal"
        if (!"normal".equals(imageStatus)) {
            throw new Exception((isFront ? "Front" : "Back") + " image_status 无效: " + imageStatus);
        }

        // 判断 risk_type 是否为正常（例如 "normal"）
        if (!"normal".equals(riskType)) {
            throw new Exception((isFront ? "Front" : "Back") + " risk_type 异常: " + riskType);
        }

        // 判断是否识别到关键字段
        int wordsResultNum = Integer.parseInt(extractField(responseResult, "words_result_num"));
        if (wordsResultNum <= 0) {
            throw new Exception((isFront ? "Front" : "Back") + " words_result 为空或无效.");
        }
    }

    /**
     * 调用百度API进行营业执照识别
     *
     * @param businessFile 图像URL
     * @return 识别结果的字符串
     * @throws Exception 可能抛出的异常
     */
    public String businessRecognition(String businessFile) throws Exception {

        // 使用 x-www-form-urlencoded 格式
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        String url = baiduProperties.getBlUrl() + "?access_token=" + getAccessToken();

        // 构建请求体，URL进行编码
        String bodyContent = "url=" + businessFile + "&detect_quality=false";
        RequestBody body = RequestBody.create(mediaType, bodyContent);

        // 构建请求
        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            int statusCode = response.code();

            // 如果返回的状态码不是200，则抛出异常
            if (statusCode != 200) {
                String errorMessage = "请求失败，状态码：" + statusCode + "，响应内容：" + response.body().string();
                throw new Exception(errorMessage);  // 或者抛出一个自定义异常
            }

            // 返回成功的响应
            return response.body().string();
        } catch (IOException e) {
            throw new Exception("IO异常，调用商业识别API时出错: " + e.getMessage(), e);
        } catch (Exception e) {
            throw new Exception("调用商业识别API时出错: " + e.getMessage(), e);
        }
    }

    private String extractField(String json, String fieldName) {
        String[] split = json.split("\"" + fieldName + "\":");
        if (split.length > 1) {
            String valuePart = split[1];
            // 处理字符串值或数字值
            if (valuePart.startsWith("\"")) {
                return valuePart.split("\"")[1];
            } else {
                return valuePart.split(",|}")[0];
            }
        }
        return null;
    }

    private String extractToken(String response) {
        return response.split("\"access_token\":\"")[1].split("\"")[0];
    }

}
